package cn.xinfei.xdecision.common.utils.util;

import lombok.extern.slf4j.Slf4j;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

@Slf4j
public class DateUtils {

    private DateUtils() {

    }

    public static final String yyyyMMdd = "yyyyMMdd";
    public static final String FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss";
    public static DateTimeFormatter DEFAULT_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    public static DateTimeFormatter DEFAULT_DATE_TIME_FORMATTER_MS = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
    private static DateTimeFormatter DEFAULT_DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    private static DateTimeFormatter DEFAULT_TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss");

    private static ZoneId ZONE_ID_SHANGHAI = ZoneId.of("Asia/Shanghai");

    public static Long getCurrent2TodayEndMillisTime() {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        return todayEnd.getTimeInMillis() - System.currentTimeMillis();
    }

    /**
     * @param date    日期
     * @param pattern 指定需要转换成的字符串格式
     */
    public static String dateToString(Date date, String pattern) {
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        return format.format(date);
    }

    /**
     * 获取当前时间
     */
    public static Date getCurrentDate() {
        Calendar calendar = new GregorianCalendar();
        return calendar.getTime();

    }
    public static String getCurrentStrDate() {
        Calendar calendar = new GregorianCalendar();
        return new SimpleDateFormat(FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND).format(calendar.getTime());
    }

    public static String formatDate(Date date, String pattern) {
        return new SimpleDateFormat(pattern).format(date);
    }


    /**
     * 日期字符串转化为Date类型
     */
    public static Date strToDate(String dateStr, String pattern) throws ParseException {
        SimpleDateFormat formatter = new SimpleDateFormat(pattern);
        return formatter.parse(dateStr);
    }

    /**
     * 比较两个Date类型的日期时间(仅仅比较年月日,忽略时分秒)
     */
    public static boolean sameDate(Date d1, Date d2) {
        SimpleDateFormat fmt = new SimpleDateFormat(yyyyMMdd);
        return fmt.format(d1).equals(fmt.format(d2));
    }

    /**
     * 获取指定日期距离当前日期的天数
     *
     * @param timestamp 指定时间戳
     * @return 天数
     */
    public static int getArriveCurrentDays(long timestamp) {
        return (int) (LocalDate.now().toEpochDay() - Instant.ofEpochMilli(timestamp).atZone(ZoneId.systemDefault()).toLocalDate().toEpochDay());
    }

    /**
     * 返回时间格式如：2023-03-20 00:00:00
     */
    public static Date getStartOfDay(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 返回数小时之前的数据
     * @param num
     * @return
     */
    public static Date getBeforeNumHour(int num) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR_OF_DAY,num);
        return calendar.getTime();
    }
    public static Date getBeforeNumDay(int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH,-day);
        return calendar.getTime();
    }

    public static String getBeforeNumDayDate(int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH,-day);
        return new SimpleDateFormat(FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND).format(calendar.getTime());
    }
    /**
     * 返回时间格式如：2023-03-20 23:59:59
     */
    public static Date getEndOfDay(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    public static String getCurrentLocalDateTimeMs(){
        LocalDateTime localDateTime = LocalDateTime.now(ZONE_ID_SHANGHAI);
        return localDateTime.format(DEFAULT_DATE_TIME_FORMATTER_MS);
    }

    public static String getCurrentDate(String aFormat) {
        TimeZone timeZone = TimeZone.getTimeZone("GMT+8:00");
        SimpleDateFormat format = new SimpleDateFormat(aFormat);
        format.setTimeZone(timeZone);
        return format.format(new Date(System.currentTimeMillis()));
    }

    public static String getSfyCurrentDateTime() {
        return getCurrentDate("yyyy-MM-dd HH:mm:ss");
    }

    public static String getDateAfterDays(String strDate, int days) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date date = format.parse(strDate);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.DATE, days);
            date = calendar.getTime();
            strDate = format.format(date);
        } catch (ParseException e) {
            log.error("ParseException strDate["+strDate+"]", e);
        }

        return strDate;
    }
}
